package com.lexton.util.excel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPicture;
import org.apache.poi.hssf.usermodel.HSSFPictureData;
import org.apache.poi.hssf.usermodel.HSSFShape;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFPicture;
import org.apache.poi.xssf.usermodel.XSSFShape;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFSimpleShape;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;

/**
 * 利用POI获取Excel中图片和图片位置（支持excel2003or2007多sheet）
 * http://blog.csdn.net/delongcpp/article/details/8833995
 * 获取excel中 图片，并得到图片位置，支持03 07 多sheet，支持每个格子有多张图片
 */
public class ExcelPictureUtil {
	public static Map<String, List<PictureData>> getSheetPictrues(Workbook workbook, Sheet sheet, int sheetNum, String ext) {
		if ("xls".equals(ext)) {
			return getSheetPictrues03((HSSFWorkbook)workbook, (HSSFSheet)sheet, sheetNum);
		} else {
			return getSheetPictrues07((XSSFWorkbook)workbook, (XSSFSheet)sheet, sheetNum);
		}
	}
	
	/** 
	 * 获取Excel2003图片 
	 * @param sheetNum 当前sheet编号 
	 * @param sheet 当前sheet对象 
	 * @param workbook 工作簿对象 
	 * @return Map key:图片单元格索引（0_1_1）String，value:图片流PictureData 
	 * @throws IOException 
	 */
	public static Map<String, List<PictureData>> getSheetPictrues03(HSSFWorkbook workbook, HSSFSheet sheet, int sheetNum) {
		Map<String, List<PictureData>> reslt = new HashMap<String, List<PictureData>>();
		List<HSSFPictureData> pictures = workbook.getAllPictures();
		
		if (pictures.size() != 0) {
			for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) {
				HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();
				if (shape instanceof HSSFPicture) {
					HSSFPicture pic = (HSSFPicture) shape;
					int pictureIndex = pic.getPictureIndex() - 1;
					HSSFPictureData picData = pictures.get(pictureIndex);
					String picIndex = String.valueOf(sheetNum) + "_" + String.valueOf(anchor.getRow1()) + "_" + String.valueOf(anchor.getCol1());
					List<PictureData> temp = reslt.get(picIndex);
					if (temp == null) {
						temp = new ArrayList<PictureData>();
					}
					temp.add(picData);
					reslt.put(picIndex, temp);
				}
			}
			return reslt;
		} else {
			return null;
		}
	}

	/** 
	 * 获取Excel2007图片 
	 * @param sheetNum 当前sheet编号 
	 * @param sheet 当前sheet对象 
	 * @param workbook 工作簿对象 
	 * @return Map key:图片单元格索引（0_1_1）String，value:图片流PictureData 
	 */
	public static Map<String, List<PictureData>> getSheetPictrues07(XSSFWorkbook workbook, XSSFSheet sheet, int sheetNum) {
		Map<String, List<PictureData>> reslt = new HashMap<String, List<PictureData>>();

		for (POIXMLDocumentPart dr : sheet.getRelations()) {
			if (dr instanceof XSSFDrawing) {
				XSSFDrawing drawing = (XSSFDrawing) dr;
				List<XSSFShape> shapes = drawing.getShapes();
				for (XSSFShape shape : shapes) {
					if (shape instanceof XSSFPicture) {
						XSSFPicture pic = (XSSFPicture) shape;
						XSSFClientAnchor anchor = pic.getPreferredSize();
						CTMarker ctMarker = anchor.getFrom();
						String picIndex = String.valueOf(sheetNum) + "_" + ctMarker.getRow() + "_" + ctMarker.getCol();
						
						List<PictureData> temp = reslt.get(picIndex);
						if (temp == null) {
							temp = new ArrayList<PictureData>();
						}
						temp.add(pic.getPictureData());
						reslt.put(picIndex, temp);
					} else if (shape instanceof XSSFSimpleShape) {
//						XSSFSimpleShape pic = (XSSFSimpleShape) shape;
//						XSSFAnchor anchor = pic.getAnchor();
//						String picIndex = String.valueOf(sheetNum) + "_" + anchor.getDx1() + "_" + anchor.getDy1();
//						List<PictureData> temp = reslt.get(picIndex);
//						if (temp == null) {
//							temp = new ArrayList<PictureData>();
//						}
//						temp.add(pic.getDrawing());
//						reslt.put(picIndex, temp);
					}
				}
			}
		}

		return reslt;
	}
	
	public static void printPicture(String exportPath, Map<String, List<PictureData>> map) throws Exception {
		Object key[] = map.keySet().toArray();
		for (int i = 0; i < map.size(); i++) {
			int j=0;
			for (PictureData pic : map.get(key[i])) {
				// 获取图片流
				//PictureData pic = map.get(key[i]);
				// 获取图片索引
				String picName = key[i].toString();
				// 获取图片格式
				String ext = pic.suggestFileExtension();
				
				byte[] data = pic.getData();
				
				File file = new File(exportPath + "/");
				if (file.exists()) {
					file.delete();
				}
				file.mkdir();
				FileOutputStream out = new FileOutputStream(exportPath + "/" + picName+"_"+j + "." + ext);
				out.write(data);
				out.close();
				j++;
			}
		}
	}
	
	public static void printImg(List<Map<String, List<PictureData>>> sheetList) throws IOException {
		for (Map<String, List<PictureData>> map : sheetList) {
			Object key[] = map.keySet().toArray();
			for (int i = 0; i < map.size(); i++) {
				int j=0;
				for (PictureData pic : map.get(key[i])) {
					// 获取图片流
					//PictureData pic = map.get(key[i]);
					// 获取图片索引
					String picName = key[i].toString();
					// 获取图片格式
					String ext = pic.suggestFileExtension();
					
					byte[] data = pic.getData();
					
					FileOutputStream out = new FileOutputStream("C:/Users/Jimmy/Desktop/temp/" + picName+"_"+j + "." + ext);
					out.write(data);
					out.close();
					j++;
				}
			}
		}
		
	}
	
	/** 
	 * @param args 
	 * @throws IOException
	 * @throws InvalidFormatException
	 */
	public static void main(String[] args) throws InvalidFormatException, IOException {
		String filepath = "C:/Users/Jimmy/Desktop/供应商/2016海景家具报价表20160819.xls";
		// 创建文件
		File file = new File(filepath);
		
		// 创建流
		InputStream input = new FileInputStream(file);
		
		// 获取文件后缀名
		String fileExt =file.getName().substring(file.getName().lastIndexOf(".") + 1);
		
		// 创建Workbook
		Workbook wb = null;
		
		// 创建sheet
		Sheet sheet = null;

		//根据后缀判断excel 2003 or 2007+
		if (fileExt.equals("xls")) {
			wb = (HSSFWorkbook) WorkbookFactory.create(input);
		} else {
			wb = new XSSFWorkbook(input);
		}
		
		//获取excel sheet总数
		int sheetNumbers = wb.getNumberOfSheets();
		
		// sheet list
		List<Map<String, List<PictureData>>> sheetList = new ArrayList<Map<String, List<PictureData>>>();
		
		// 循环sheet
		for (int i = 0; i < sheetNumbers; i++) {
			
			sheet = wb.getSheetAt(i);
			// map等待存储excel图片
			Map<String, List<PictureData>> sheetIndexPicMap;
			
			// 判断用07还是03的方法获取图片
			if (fileExt.equals("xls")) {
				sheetIndexPicMap = getSheetPictrues03((HSSFWorkbook) wb, (HSSFSheet) sheet, i);
			} else {
				sheetIndexPicMap = getSheetPictrues07((XSSFWorkbook) wb, (XSSFSheet) sheet, i);
			}
			// 将当前sheet图片map存入list
			sheetList.add(sheetIndexPicMap);
		}
		
		printImg(sheetList);
	}

	
}
